package emailserving.controller;

import com.avaje.ebean.EbeanServer;
import emailserving.common.Utils;
import emailserving.component.JobService;
import emailserving.config.AppMetadataConfig;
import emailserving.domain.Contact;
import emailserving.domain.Content;
import emailserving.domain.Job;
import emailserving.pageView.JobValueObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.mail.MessagingException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Controller
public class IndexController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Autowired
    AppMetadataConfig appMetadataConfig;

    @Autowired
    EbeanServer ebeanServer;

    @Autowired
    JobService jobService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView index(@RequestParam(name = "name", required = true, defaultValue = "") String name,
                              @RequestParam(name = "p", required = true, defaultValue = "0") int p) {
        ModelAndView mav = new ModelAndView("index");
        List<Job> jobs = jobService.findJobNameLike(name, p);
        mav.addObject("jobs", JobValueObject.createByJobs(jobs, jobService.jobExecutingStatusesOf(jobs)));
        return mav;
    }

    @RequestMapping(value = "/start-job", method = RequestMethod.GET)
    public ModelAndView startJob(@RequestParam(name = "jobId", required = true) long jobId) throws MessagingException {
        jobService.executeJob(jobId);
        return new ModelAndView("redirect:/");
    }


    @RequestMapping(value = "/stop-job", method = RequestMethod.GET)
    public ModelAndView stopJob(@RequestParam(name = "jobId", required = true) long jobId) throws MessagingException {
        jobService.stopJob(jobId);
        return new ModelAndView("redirect:/");
    }



    @RequestMapping(value = "/create-job", method = RequestMethod.POST)
    public ModelAndView createJob(@RequestParam(name = "contacts") MultipartFile contacts,
                                  @RequestParam(name = "content") MultipartFile content,
                                  @RequestParam("name") String jobName,
                                  @RequestParam(value = "senderEmail", required = false, defaultValue = "") String senderEmail,
                                  @RequestParam("subject") String subject) throws IOException {

        String contactsTxt = new String(contacts.getBytes(), "UTF-8");
        String contentTxt = new String(content.getBytes(), "UTF-8");
        jobService.createJob(jobName,
                appMetadataConfig.getSenderEmail(),
                createContentWithoutJob(subject, contentTxt),
                createContactsWithoutJobListFrom(contactsTxt));
        return new ModelAndView("redirect:/");
    }

    private Content createContentWithoutJob(String subject, String content) {
        return new Content(subject, content);
    }


    private List<Contact> createContactsWithoutJobListFrom(String contactsTxtWithLine) {
        return Arrays.asList(contactsTxtWithLine.split("\\r?\\n")).stream()
                .filter(StringUtils::isNotBlank)
                .filter(Utils::validateItsEmailFormat)
                .map(StringUtils::trim)
                .distinct()
                .map(Contact::createByEmail)
                .collect(Collectors.toList());
    }

    @RequestMapping(value = "/refresh-job", method = RequestMethod.GET)
    public ModelAndView refreshJobStatus() {
        jobService.refresh();
        return new ModelAndView("redirect:/");
    }


//
//    @RequestMapping(value = "/search", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
//    @ResponseBody
//    public List<Todo> search(@RequestParam(name = "q", required = false, defaultValue = "") String q,
//                             @RequestParam(name = "p", required = false, defaultValue = "0") int p) {
//        logger.debug("search : " + q);
//        return server.find(Todo.class).where().like("title", "%" + q + "%").findPagedList(p, 20).getList();
//    }

}
